package org.example.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import org.example.core.web.PageResult;
import org.example.core.web.Result;
import org.example.sys.entity.TSysRole;
import org.example.sys.entity.base.PageParam;
import org.example.sys.entity.param.RoleParam;
import org.example.sys.service.TSysRoleService;
import org.example.sys.utils.CommonUtil;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色表(TSysRole)表控制层
 */
@RestController
@RequestMapping("/api/system/role")
public class TSysRoleController extends ApiController {
    @Resource
    private TSysRoleService roleService;

    @PreAuthorize("hasAuthority('sys:role:list')")
    @Operation(summary = "分页查询角色")
    @GetMapping("/page")
    public Result<PageResult<TSysRole>> page(RoleParam param) {
        PageParam<TSysRole, RoleParam> page = new PageParam<>(param);
        return success(roleService.page(page, page.getWrapper()));
    }

    @PreAuthorize("hasAuthority('sys:role:list')")
    @Operation(summary = "查询全部角色")
    @GetMapping()
    public Result<List<TSysRole>> list(RoleParam param) {
        PageParam<TSysRole, RoleParam> page = new PageParam<>(param);
        return success(roleService.list(page.getOrderWrapper()));
    }

    @PreAuthorize("hasAuthority('sys:role:list')")
    @Operation(summary = "根据id查询角色")
    @GetMapping("/{id}")
    public Result<TSysRole> get(@PathVariable("id") Integer id) {
        return success(roleService.getById(id));
    }

    @PreAuthorize("hasAuthority('sys:role:save')")
    @Operation(summary = "添加角色")
    @PostMapping()
    public Result<?> save(@RequestBody TSysRole role) {
        if (isRoleCodeOrNameExists(role.getRoleCode(), role.getRoleName(), null)) {
            return fail("角色标识或名称已存在");
        }
        if (roleService.save(role)) {
            return success("添加成功");
        }
        return fail("添加失败");
    }

    @PreAuthorize("hasAuthority('sys:role:update')")
    @Operation(summary = "修改角色")
    @PutMapping()
    public Result<?> update(@RequestBody TSysRole role) {
        if (isRoleCodeOrNameExists(role.getRoleCode(), role.getRoleName(), role.getRoleId())) {
            return fail("角色标识或名称已存在");
        }
        if (roleService.updateById(role)) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('sys:role:remove')")
    @Operation(summary = "删除角色")
    @DeleteMapping("/{id}")
    public Result<?> remove(@PathVariable("id") Integer id) {
        if (roleService.removeById(id)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    @PreAuthorize("hasAuthority('sys:role:save')")
    @Operation(summary = "批量添加角色")
    @PostMapping("/batch")
    public Result<List<String>> saveBatch(@RequestBody List<TSysRole> list) {
        if (CommonUtil.checkRepeat(list, TSysRole::getRoleName) || CommonUtil.checkRepeat(list, TSysRole::getRoleCode)) {
            return fail("角色名称或标识存在重复", null);
        }
        List<TSysRole> codeExists = roleService.list(new LambdaQueryWrapper<TSysRole>().in(TSysRole::getRoleCode,
                list.stream().map(TSysRole::getRoleCode).collect(Collectors.toList())));
        if (!codeExists.isEmpty()) {
            return fail("角色标识已存在", codeExists.stream().map(TSysRole::getRoleCode).collect(Collectors.toList()));
        }
        List<TSysRole> nameExists = roleService.list(new LambdaQueryWrapper<TSysRole>().in(TSysRole::getRoleName,
                list.stream().map(TSysRole::getRoleName).collect(Collectors.toList())));
        if (!nameExists.isEmpty()) {
            return fail("角色名称已存在", nameExists.stream().map(TSysRole::getRoleName).collect(Collectors.toList()));
        }
        if (roleService.saveBatch(list)) {
            return success("添加成功", null);
        }
        return fail("添加失败", null);
    }

    @PreAuthorize("hasAuthority('sys:role:remove')")
    @Operation(summary = "批量删除角色")
    @DeleteMapping("/batch")
    public Result<?> removeBatch(@RequestBody List<Integer> ids) {
        if (roleService.removeByIds(ids)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    private boolean isRoleCodeOrNameExists(String roleCode, String roleName, Long excludeId) {
        return roleService.count(new LambdaQueryWrapper<TSysRole>()
                .eq(TSysRole::getRoleCode, roleCode)
                .ne(excludeId != null, TSysRole::getRoleId, excludeId)) > 0
                || roleService.count(new LambdaQueryWrapper<TSysRole>()
                .eq(TSysRole::getRoleName, roleName)
                .ne(excludeId != null, TSysRole::getRoleId, excludeId)) > 0;
    }
}